#include "unistd.h"
#include "error.h"
#include "utility/type.h"

#include <cstdarg>
#include <unistd.h>


namespace _ {

STATIC_ASSERT_SIMPLE(Wrap::STDIN_FIFENO_ == STDIN_FILENO);
STATIC_ASSERT_SIMPLE(Wrap::STDOUT_FILENO_ == STDOUT_FILENO);
STATIC_ASSERT_SIMPLE(Wrap::STDERR_FILENO_ == STDERR_FILENO);

}

int Wrap::sc_clk_tck() {
    return _SC_CLK_TCK;
}

int Wrap::sc_page_size() {
    return _SC_PAGE_SIZE;
}

int Wrap::close_(int fd) {
    return PERROR_NEQ0(::close(fd));
}

pid_t Wrap::fork_() {
    return PERROR_NEG(::fork());
}

int Wrap::gethostname_(char *name, size_t len) {
    return PERROR_NEQ0(::gethostname(name, len));
}

uid_t Wrap::geteuid_() {
    return ::geteuid();
}

pid_t Wrap::getpid_() {
    return ::getpid();
}

pid_t Wrap::getppid_() {
    return ::getppid();
}

uid_t Wrap::getuid_() {
    return ::getuid();
}

ssize_t Wrap::pread_(int fd, void *buf, size_t nbytes, off_t offset) {
    return PERROR_NEG(::pread(fd, buf, nbytes, offset));
}

ssize_t Wrap::read_(int fd, void *buf, size_t nbytes) {
    return PERROR_NEG(::read(fd, buf, nbytes));
}

ssize_t Wrap::readlink_(const char *path, char *buf, size_t bytes) {
    return PERROR_NEG(::readlink(path, buf, bytes));
}

unsigned Wrap::sleep_(unsigned seconds) {
    auto result = ::sleep(seconds);
    if (result != 0) {
        ::printf("sleep was interrupted & left %u seconds", result);
    }
    return result;
}


long Wrap::syscall_(long sysno, ...) {
    va_list args{};
    va_start(args, sysno);
    auto result = ::syscall(sysno, args);
    va_end(args);

    return PERROR_NEG(result);
}

long Wrap::sysconf_(int name) {
    return PERROR_NEG(::sysconf(name));
}

ssize_t Wrap::write_(int fd, const void *buf, size_t n) {
    return PERROR_NEG(::write(fd, buf, n));
}
